package ruru.client.ui.widgets;

import java.util.ArrayList;
import java.util.List;

import ruru.client.RuruDkp;
import ruru.client.backend.RuruUtility;
import ruru.client.backend.item.BankItem;
import ruru.client.backend.rpcWrapper.BankItemWrapper;
import ruru.client.backend.rpcWrapper.BankWrapper;
import ruru.client.services.DataService;
import ruru.client.services.DataServiceAsync;
import ruru.client.ui.widgets.sortableTable.Sortable;
import ruru.client.ui.widgets.sortableTable.SortableTable;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.RowFormatter;

public class BankWidget extends Composite {
	/** Bank's name */
	private String name;

	/** Bank's description */
	private String description;

	/** A sortable table that includes standings information */
	private SortableTable table;

	/** Main widget's panel that includes both the standings table and the "last updated" label */
	private VerticalPanel panel;

	/** Label that tells when the standings table was last updated */
	private HTML updated;

	/** Label that shows how much gold is in the bank */
	private HTML gold;

	/** Title of bank */
	private HTML title;

	/** Description of bank */
	private Label desc;

	/** List of BankItems */
	private List inventory;

	/** Has this widget been loaded already? */
	private boolean initalized = false;

	public BankWidget(String name, String description) {
		this.name = name;
		this.description = description;

		panel = new VerticalPanel();
		table = new SortableTable();
		inventory = new ArrayList();

		title = new HTML(this.name);
		desc = new HTML("Description: " + this.description);

		gold = new HTML();
		updated = new HTML();

		panel.add(title);
		panel.add(desc);
		panel.add(updated);
		panel.add(gold);
		panel.add(table);

		title.addStyleName("text-center");
		title.addStyleName("bank-title");
		desc.addStyleName("text-center");
		gold.addStyleName("text-center");
		updated.addStyleName("text-center");

		table.setWidth("100%");
		initWidget(panel);
	}

	/**
	 * Gets bank information for Zul'Gurub (trollpuffin)
	 */
	public void getReducksData(final VerticalPanel bankList, final BankWidget reducks) {
		DataServiceAsync ds = (DataServiceAsync) GWT.create(DataService.class);
		ServiceDefTarget endpoint = (ServiceDefTarget) ds;
		String moduleRelativeURL = GWT.getModuleBaseURL() + "/DataService";
		endpoint.setServiceEntryPoint(moduleRelativeURL);
		AsyncCallback callback = new AsyncCallback() {

			/**/
			public void onSuccess(Object result) {
				init((BankWrapper) result);
				setWidth("100%");
				bankList.clear();
				bankList.add(reducks);
				System.out.println("reducks bank loaded in client: " + (System.currentTimeMillis() - RuruDkp.start) + "ms");
			}

			/**/

			public void onFailure(Throwable caught) {
				System.out.println("in client: getReducksData failure");
				caught.printStackTrace();
			}
		};
		ds.getReducksData(callback);
	}

	private void initTable() {
		table.addColumnHeader("", 0);
		table.addColumnHeader("Name", 1);
		table.addColumnHeader("Type", 2);

		for(int i = 0; i < inventory.size(); i++) {
			BankItem b = (BankItem) inventory.get(i);
			ItemLink link = new ItemLink(b.getName());

			String[] type = b.getType().split("[ ]");
			List typeList = new ArrayList();
			for(int j = 0; j < type.length; j++) {
				typeList.add(type[j]);
			}

			table.setValue(i + 1, 0, new Integer(b.getQuantity()));
			table.setValue(i + 1, 1, link);
			table.setValue(i + 1, 2, RuruUtility.capitalize(typeList));
		}

		table.addStyleName("sortable-table");
		table.setCellSpacing(0);

		// Set Style Name for the header
		RowFormatter rowFormatter = table.getRowFormatter();
		rowFormatter.addStyleName(0, "standings-tableHeader");

		CellFormatter cellFormatter = table.getCellFormatter();

		for(int i = 0; i < table.getRowCount(); i++) {
			cellFormatter.setWidth(i, 0, "10%");
			cellFormatter.setWidth(i, 1, "60%");
			cellFormatter.setWidth(i, 2, "30%");
		}

		for(int rowIndex = inventory.size(); rowIndex > 0; rowIndex--) {
			rowFormatter.addStyleName(rowIndex, "row");
		}
		
		for(int k = 0; k < inventory.size() + 1; k++) {
			for(int j = 0; j < 3; j++) {
				cellFormatter.setStyleName(k, j, "sortable-table-cell");
				if(j == 0) {
					cellFormatter.addStyleName(k, j, "text-right");
				}
			}
		}

		table.forceSort(2, Sortable.SORT_ASC);
	}

	/**
	 * Reads a BankWrapper object from the server and populates this bank.
	 * 
	 * @param fromServer
	 */
	public void init(BankWrapper fromServer) {
		if(!initalized) {
			long lastBankUpdate =  fromServer.getLastUpdated();
			updated.setHTML("Last updated: " + RuruUtility.lastUpdate(lastBankUpdate) + " ago");
			gold.setHTML("Current gold: " + fromServer.getGold() + "g");

			List wrappers = fromServer.getBankItemWrappers();
			for(int i = 0; i < wrappers.size(); i++) {
				BankItemWrapper wrapper = (BankItemWrapper) wrappers.get(i);
//				if(wrapper.getAmbiguous()) {
//					inventory.add(new AmbiguousBankItem(wrapper.getQuantity(), wrapper.getName(), wrapper.getType(), wrapper
//							.getID()));
//				} else
				inventory.add(new BankItem(wrapper.getQuantity(), wrapper.getName(), wrapper.getType()));
			}

			initTable();
			initalized = true;
		}
	}
}